/**
 * @file Levetop_uart.c
 * @author Zhai Tao (zhaitao.as@outlook.com)
 * @brief
 * @version 0.1
 * @date 2022-04-24
 *
 * @copyright zhaitao.as@outlook.com (c) 2022
 *
 */

#include "Levetop_uart.h"
#include "printf.h"
#include <stdlib.h>
#include <string.h>

unsigned int Rx_CRC_CCITT(unsigned char *puchMsg, unsigned int usDataLen);

unsigned int Rx_CRC_CCITT(unsigned char *puchMsg, unsigned int usDataLen)
{
	unsigned char i = 0;
	unsigned short wCRCin = 0x0000;
	unsigned short wCPoly = 0x1021;
	unsigned char wChar = 0;

	while (usDataLen--) {
		wChar = *(puchMsg++);
		wCRCin ^= (wChar << 8);
		for (i = 0; i < 8; i++) {
			if (wCRCin & 0x8000)
				wCRCin = (wCRCin << 1) ^ wCPoly;
			else
				wCRCin = wCRCin << 1;
		}
	}
	return (wCRCin);
}

int levetop_packet_size(const char *content)
{
	size_t content_len = strlen(content);
	return content_len + 9;
}

int levetop_pack(unsigned char *dest, unsigned cmd, unsigned index, char *c, unsigned long len)
{
	int csize = len;
	int psize = csize + 9;
	// printf("content size: %d\r\n", csize);

	char pack[256];
	// char *pack = malloc(psize);

	if (pack == 0) {
		// printf("malloc failed\r\n");
		return -1;
	}
	memset(pack, 0, psize);

	pack[0] = 0xAA;
	pack[1] = cmd;
	pack[2] = index;
	memcpy(&pack[3], c, csize);

	int crc = Rx_CRC_CCITT((unsigned char *)&pack[1], csize + 2);

	pack[csize + 3] = crc >> 8 & 0xff;
	pack[csize + 4] = crc & 0xff;
	pack[csize + 5] = 0xE4;
	pack[csize + 6] = 0x1B;
	pack[csize + 7] = 0x11;
	pack[csize + 8] = 0xEE;
	pack[csize + 9] = 0;

	for(int i  = 0; i < psize; i++){
		dest[i] = pack[i];
	}

	return psize;
}

//发送指令函数
int levetop_pack2(unsigned char *dest, unsigned cmd, unsigned index, char *c)
{
	unsigned char Sendbuff[100] = {0};
	// unsigned char *Sendbuff = (unsigned char *)dest;

	unsigned short Send_CRC = 0;
	unsigned char C_flag = 0; //判断是否在" "中

	int i = 0, j = 0;

	//只有第一个和第二个字符是有效的才是指令
	if (((c[0] >= 0x30 && c[0] <= 0x39) || (c[0] >= 0x41 && c[0] <= 0x5A)) || ((c[1] >= 0x30 && c[1] <= 0x39) || (c[1] >= 0x41 && c[1] <= 0x5A))) {
		while (c[i] != '\0') {

			//排除空格，非空格可以进入
			if (c[i] != ' ') {
				//当" "中的字符  以 ASCII 输出，不需要输出"  号，
				if (c[i] == '"') {
					C_flag++;
					i++;
				}

				if (C_flag == 1) {
					if (c[i] != '"') {
						Sendbuff[j] = c[i]; // ASCII  直接输出
						i++;
						j++;
					}

				} else if (C_flag == 2) {
					//第二次遇到"
					C_flag = 0;
					i++;
				}

				if (C_flag == 0) {
					if (c[i] == '/')
						break;

					if (c[i] >= 0x30 && c[i] <= 0x39) // 0~9
					{
						Sendbuff[j] = ((c[i] - 0x30) << 4);
						i++;

						if (c[i] >= 0x30 && c[i] <= 0x39) {
							Sendbuff[j] += (c[i] - 0x30);
							i++;
							j++;
						} else if (c[i] >= 0x41 && c[i] <= 0x5A) {
							Sendbuff[j] += (c[i] - 0x37);
							i++;
							j++;
						}
					}

					else if (c[i] >= 0x41 && c[i] <= 0x5A) // A~Z
					{
						Sendbuff[j] = ((c[i] - 0x37) << 4);
						i++;

						if (c[i] >= 0x30 && c[i] <= 0x39) {
							Sendbuff[j] += (c[i] - 0x30);
							i++;
							j++;
						} else if (c[i] >= 0x41 && c[i] <= 0x5A) {
							Sendbuff[j] += (c[i] - 0x37);
							i++;

							j++;
						}
					}
				}
			} else
				i++;
		}
		Sendbuff[j] = '\0';
		// printf("%s\r\n",Sendbuff);

		/************************CRC 和针头针尾************************/

		Send_CRC = Rx_CRC_CCITT(Sendbuff, j);

		Sendbuff[j] = Send_CRC >> 8 & 0xff;
		Sendbuff[j + 1] = Send_CRC & 0xff;

		for (i = 0; i < j + 2; i++)
			Sendbuff[j + 2 - i] = Sendbuff[j + 1 - i]; //挪位

		Sendbuff[0] = 0xAA;
		Sendbuff[j + 3] = 0xE4;
		Sendbuff[j + 4] = 0x1B;
		Sendbuff[j + 5] = 0x11;
		Sendbuff[j + 6] = 0xEE;

		j += 7;

		for (i = 0; i < j; i++) {
			/* TODO
			USART_DATA(USART0) = (uint8_t)Sendbuff[i];
			while (usart_flag_get(USART0, USART_FLAG_TBE) == 0) {
			}; //循环发送,直到发送完毕*/
		}

		Sendbuff[j] = 0;
		printf("%s\r\n", Sendbuff);

		return 0;
	}

	return -1;
}
